﻿using ProjScan.Modules;
using ProjScan.Tools;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace ProjScan.RecordManager.AssetData
{
    internal class MaterialAssetData : UnityCreatableAssetData<Material>
    {
        public bool IsMaterialUnused;

        public string ShaderName;

        public MaterialProperty[] MaterialProperties;

        private static int DebugCounter = 3;

        private string assetPath;

        public MaterialAssetData(int directoryId, string filePath, Material material)
        {
            ScanLog.Instance.LogScanInfo(Module.Basic_Assets_Check, ScanLog.Stage.s3, "DetailedInfo(Material)", "MaterialRecord.Ctor");
            asset = material;
            assetName = Path.GetFileName(filePath);
            assetDirectoryID = directoryId;
            IsMaterialUnused = CheckUnusedTexture(material);
            MaterialProperties = TexturePropertiesInMaterial(material);
            ShaderName = material.shader.name;
            assetPath = AssetDatabase.GetAssetPath(asset);
            ScanLog.Instance.LogScanInfo(Module.Basic_Assets_Check, ScanLog.Stage.s3, "DetailedInfo(Material)", "MaterialRecord.Ctor Complete");
            if (DebugCounter >= 0)
            {
                DebugCounter--;
            }
        }

        private static bool CheckUnusedTexture(Material material)
        {
            ScanLog.Instance.LogScanInfo(Module.Basic_Assets_Check, ScanLog.Stage.s3, "DetailedInfo(Material)", "Enter CheckHasUnusedTexture");
            SerializedObject serializedObject = new SerializedObject(material);
            if (DebugCounter > 0)
            {
                ScanLog.Instance.LogScanInfo("ApplyModifiedProperties");
            }

            serializedObject.ApplyModifiedProperties();
            SerializedProperty serializedProperty = serializedObject.FindProperty("m_SavedProperties");
            if (DebugCounter > 0)
            {
                ScanLog.Instance.LogScanInfo("FindProperty");
            }

            if (serializedProperty != null)
            {
                SerializedProperty serializedProperty2 = serializedProperty.FindPropertyRelative("m_TexEnvs");
                if (DebugCounter > 0)
                {
                    ScanLog.Instance.LogScanInfo("FindPropertyRelative");
                }

                if (serializedProperty2 == null)
                {
                    return false;
                }

                for (int i = 0; i < serializedProperty2.arraySize; i++)
                {
                    SerializedProperty arrayElementAtIndex = serializedProperty2.GetArrayElementAtIndex(i);
                    string stringValue = arrayElementAtIndex.FindPropertyRelative("first").stringValue;
                    if (!material.HasProperty(stringValue))
                    {
                        Texture x = arrayElementAtIndex.FindPropertyRelative("second").FindPropertyRelative("m_Texture").objectReferenceValue as Texture;
                        if (DebugCounter > 0)
                        {
                            ScanLog.Instance.LogScanInfo("GetTexture");
                        }

                        if (x != null)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }

        public static MaterialProperty[] TexturePropertiesInMaterial(Material material)
        {
            ScanLog.Instance.LogScanInfo(Module.Basic_Assets_Check, ScanLog.Stage.s3, "DetailedInfo(Material)", "Enter GetTexturePropertiesInMat");
            if (material == null)
            {
                return new MaterialProperty[0];
            }

            List<MaterialProperty> list = new List<MaterialProperty>();
            ShaderUtil.GetPropertyCount(material.shader);
            Object[] mats = new Object[1]
            {
                material
            };
            MaterialProperty[] materialProperties = MaterialEditor.GetMaterialProperties(mats);
            if (DebugCounter > 0)
            {
                ScanLog.Instance.LogScanInfo("GetMaterialProperties");
            }

            MaterialProperty[] array = materialProperties;
            foreach (MaterialProperty materialProperty in array)
            {
                if (materialProperty.type == MaterialProperty.PropType.Texture)
                {
                    list.Add(materialProperty);
                    if (DebugCounter > 0)
                    {
                        ScanLog.Instance.LogScanInfo("Add PropType.Texture");
                    }
                }
            }

            return list.ToArray();
        }

        public static Texture[] MaterialTextures(Material material)
        {
            if (material == null)
            {
                return new Texture[0];
            }

            MaterialProperty[] array = TexturePropertiesInMaterial(material);
            Texture[] array2 = new Texture[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                array2[i] = array[i].textureValue;
            }

            return array2;
        }

        public override string GetCSVHeader()
        {
            return "Name,DirID,ShaderName";
        }

        public override string GetInfo()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(ToolsHelper.QuoteString(assetName));
            stringBuilder.Append(',');
            stringBuilder.Append(assetDirectoryID);
            stringBuilder.Append(',');
            stringBuilder.Append(ShaderName);
            return stringBuilder.ToString();
        }

        public override void Reset()
        {
            asset = null;
            MaterialProperties = null;
        }

        public override string GetAssetPath()
        {
            return assetPath;
        }

        public override string GetFileAssetPath()
        {
            return assetPath;
        }
    }
}